#if (!requireNamespace("ComplexHeatmap", quietly = TRUE)) BiocManager::install("ComplexHeatmap")
if (!requireNamespace("circlize", quietly = TRUE)) install.packages("circlize")
if (!requireNamespace("RColorBrewer", quietly = TRUE)) install.packages("RColorBrewer")
if (!requireNamespace("dendextend", quietly = TRUE)) install.packages("dendextend")
if (!requireNamespace("dendsort", quietly = TRUE)) install.packages("dendsort")
if (!requireNamespace("dendextend", quietly = TRUE)) install.packages("dendextend")
if (!requireNamespace("gridBase", quietly = TRUE)) install.packages("gridBase")

library(ComplexHeatmap)
library(circlize)
library(RColorBrewer)
library(dendextend)
library(dendsort)
library(dendextend)
library(gridBase)
# https://www.jianshu.com/p/3a627c02d747
# 2024年7月24日10:12:16  定版 测试 服务器版本 
try({
  setwd('F:/rproject/r-language/lilongyuan2/722/环形热图')
})
try({
    setwd('父级路径')
})
# 接受参数 进行计算 部分是通过上传的数据进行的
# 列名开头
colnameParam <- 'C'
# 行名开头
rownameParam <- 'R'
# 列数量 动态获取
colSize <- 10
# 行数量 动态获取
rowSize <- 100
#  分组数量
splitSize <- 3
# 扇形间隔大小
fanSize <- 2
# 扇形最后与开始扇形分片距离
fanLastSize <- 30
# 设置聚类树的数量
treeColorSize <- 4
# 设置说明距离左侧距离
noteLeftLenth <- 0.03
clusterTF<- TRUE
# 调色板
coloarmin <- "#FFFF00"
coloarme <- "#6699CC"
coloarmax <- "#CC6666"

#c(fanSize, fanSize, fanLastSize)
# 动态组合参数
circospar <- c()
i2 = 1
while (i2 <= (splitSize)) {
  if (i2<splitSize) {
    circospar[i2] <- fanSize
  }else{
    circospar[i2] <- fanLastSize
  }
  i2 <- i2 + 1
}


#动态读取数据
readFile <- function(x)  {
  data<- ""
  try({
    if (file.exists(x)) {
      if (grepl(".csv", x, ignore.case = TRUE) ) {
        print("读取csv文件")
        data <- read.csv(x)
        
      }else{
        print("读取txt文件")
        data <- read.table(x, header=TRUE, sep="\t")
      }
    }
  })
  
  return(data)
}
excelPath <- 'mat.txt'
excelPath2 <- 'mat2.txt'
# 可能能第二个文件不选择 不选择则部分逻辑不走 进行略过
isExist2 <- FALSE
mat<- readFile(excelPath)
mat2<- readFile(excelPath2)
mat<-as.data.frame(mat)
mat2<-as.data.frame(mat2)
colSize<-ncol(mat)
rowSize<-nrow(mat)
colSize2<-ncol(mat2)
rowSize2<-nrow(mat2)
if(colSize2!=1&&rowSize!=1){
  isExist2 <- TRUE
}
rownames(mat) <- paste0(rownameParam, 1:rowSize)
colnames(mat) <- paste0(colnameParam, 1:colSize)
split <- sample(letters[1:splitSize], rowSize, replace = TRUE)
split <- factor(split, levels = letters[1:splitSize])
if (isExist2) {
  split2 <- sample(letters[1:splitSize], rowSize2, replace = TRUE)
  split2 <- factor(split2, levels = letters[1:splitSize])
}

round(max(mat))
round(min(mat))
#########################################
# 调色板 数字区间对应的颜色区间
col_fun <- colorRamp2(c(round(min(mat)), 0, round(max(mat))), c(coloarmin,coloarme ,coloarmax ))
###################################
# 配色网站  https://www.58pic.com/peisebiao
Cairo::CairoTIFF(file="circlize.tiff", width=8, height=8,units="in",dpi=150)
circos.clear()
#c(fanSize, fanSize, fanLastSize)
circos.par(gap.after =circospar )
circos.heatmap(mat, #数据
               split = split, #分组 
               cluster = clusterTF, #是不是聚类 也就是显不显示树 false 下面一些参数就无效了 还有标记
               col = col_fun, # 颜色
               dend.side = "inside", # 树在圆圈内还是在外
               dend.track.height = 0.2,# 控制树的高度
               rownames.side = "outside", # 列名在圆圈内还是圆圈外 树和列不能同一侧
               rownames.col = '#CC9999', # 行名颜色
               rownames.cex = 0.7, # 字体大小
               rownames.font = 1.4, # 字体粗细
               track.height = 0.2,
               bg.border = "brown", # 边框背影颜色
               # 树的渲染
               dend.callback = function(dend, m, si) {
                 #设置四种颜色
                 color_branches(dend, k = treeColorSize, col = rainbow(treeColorSize))
               }
               )
if (isExist2) {
  circos.heatmap(mat2,
                 col = col_fun,
                 split=split2,
                 rownames.side="inside",
                 bg.border="red", #背景边缘颜色
                 rownames.cex=0.6
  )
}

circos.track(
  track.index = get.current.track.index(), 
  panel.fun = function(x, y) {
    if (CELL_META$sector.numeric.index == splitSize) {
      # 在最后一个扇形中
      cn = colnames(mat)
      n = length(cn)
      circos.text(
        rep(CELL_META$cell.xlim[2], n) + convert_x(1, "mm"),
        1:n - 0.5, cn, cex = 0.5, adj = c(0, 0.5),
        facing = "inside"
      )
    }
  }, 
  bg.border = NA
)
if (isExist2) {
  circos.track(
    track.index = get.current.track.index(), 
    panel.fun = function(x, y) {
      if (CELL_META$sector.numeric.index == splitSize) {
        # 在最后一个扇形中
        cn = colnames(mat2)
        n = length(cn)
        circos.text(
          rep(CELL_META$cell.xlim[2], n) + convert_x(1, "mm"),
          1:n - 0.5, cn, cex = 0.5, adj = c(0, 0.5),
          facing = "inside"
        )
      }
    }, 
    bg.border = NA
  )
}


# text(0, 0, "cluster = TRUE") # 设置中心点的说明 
# 添加左侧说明示例
lg_Exp1=Legend(title="Exp1",col_fun=col_fun,direction = c("vertical"))
if (isExist2) {
  lg_Exp2=Legend(title="Exp2",col_fun=col_fun,direction = c("vertical"))
}
circle_size= unit(noteLeftLenth,"snpc")
h= dev.size()
if (isExist2) {
  lgd_list= packLegend(lg_Exp1,lg_Exp2, max_height = unit(2*h,"inch"))
}else{
  lgd_list= packLegend(lg_Exp1, max_height = unit(2*h,"inch"))
}
draw(lgd_list, x = circle_size, just ="left")
# circos.clear()
dev.off()
##########################################

